package com.cskaoyan.gateway.controller.promo;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cskaoyan.gateway.config.CacheManager;
import com.cskaoyan.gateway.form.promo.CreatePromoOrderInfo;
import com.google.common.util.concurrent.RateLimiter;
import com.mall.commons.result.ResponseData;
import com.mall.commons.result.ResponseUtil;
import com.mall.promo.PromoService;
import com.mall.promo.dto.*;
import com.mall.user.annotation.Anoymous;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.intercepter.TokenIntercepter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@RestController
@RequestMapping("/shopping")
@Slf4j
public class PromoController {

    @Reference(timeout = 3000,check = false)
    PromoService promoService;


    RateLimiter rateLimiter;

    ExecutorService executorService;

    @Autowired
    CacheManager cacheManager;

    @PostConstruct
    public void init() {
        rateLimiter = RateLimiter.create(100);

        executorService = Executors.newFixedThreadPool(100);
    }


    @GetMapping("/seckilllist")
    @Anoymous
    public ResponseData getPromotionList(@RequestParam Integer sessionId) {
        PromoInfoRequest promoInfoRequest = new PromoInfoRequest();
        promoInfoRequest.setSessionId(sessionId);

        String yyyyMMdd = DateFormatUtils.format(new Date(), "yyyyMMdd");
        promoInfoRequest.setYyyymmdd(yyyyMMdd);
        PromoInfoResponse promoInfoResponse = promoService.getPromoList(promoInfoRequest);
        if (!promoInfoResponse.getCode().equals(SysRetCodeConstants.SUCCESS.getCode())) {
            return new ResponseUtil<>().setErrorMsg(promoInfoResponse.getMsg());
        }
        return new ResponseUtil<>().setData(promoInfoResponse);

    }


    @PostMapping("/promoProductDetail")
    public ResponseData getPromoItemDetail(@RequestBody PromoProductDetailRequest request) {

        PromoProductDetailResponse response = promoService.getPromoProductProduct(request);
        if (!response.getCode().equals(SysRetCodeConstants.SUCCESS.getCode())) {
            return new ResponseUtil<>().setErrorMsg(response.getMsg());
        }
        return new ResponseUtil<>().setData(response);
    }


    @PostMapping("/seckill")
    public ResponseData seckill(HttpServletRequest request,
                                @RequestBody CreatePromoOrderInfo createPromoOrderInfo) {

        rateLimiter.acquire();

        String userInfo = (String) request.getAttribute(TokenIntercepter.USER_INFO_KEY);
        JSONObject jsonObject = JSON.parseObject(userInfo);
        String username = (String) jsonObject.get("username");
        Integer uid = (Integer) jsonObject.get("uid");
        CreatePromoOrderRequest createPromoOrderRequest = new CreatePromoOrderRequest();
        createPromoOrderRequest.setProductId(createPromoOrderInfo.getProductId());
        createPromoOrderRequest.setPsId(createPromoOrderInfo.getPsId());
        createPromoOrderRequest.setUserId(uid.longValue());
        createPromoOrderRequest.setUsername(username);

        //增加地址信息
        createPromoOrderRequest.setAddressId(createPromoOrderInfo.getAddressId());
        createPromoOrderRequest.setStreetName(createPromoOrderInfo.getStreetName());
        createPromoOrderRequest.setTel(createPromoOrderInfo.getTel());

        String key = "promo_item_stock_not_enough_" + createPromoOrderInfo.getPsId() +"_" + createPromoOrderInfo.getProductId();
        String cache = cacheManager.checkCache(key);
        if (! StringUtils.isBlank(cache)) {
            return new ResponseUtil<>().setErrorMsg("库存已经售罄");
        }

        Future<CreatePromoOrderResponse> submit = executorService.submit(() -> {
            CreatePromoOrderResponse promoOrderInTransaction
                    = promoService.createPromoOrderInTransaction(createPromoOrderRequest);
            return promoOrderInTransaction;
        });

        CreatePromoOrderResponse createPromoOrderResponse;
        try {
            createPromoOrderResponse = submit.get();
            log.info("promo controller submit.get return " + createPromoOrderResponse.getCode());
            if (!createPromoOrderResponse.getCode().equals(SysRetCodeConstants.SUCCESS.getCode())) {
                return new ResponseUtil<>().setErrorMsg(createPromoOrderResponse.getMsg());
            }
        } catch (Exception e) {
            return new ResponseUtil<>().setErrorMsg(SysRetCodeConstants.SYSTEM_ERROR.getMessage());
        }

        return new ResponseUtil<>().setData(createPromoOrderResponse);
    }


}
